package com.share.device.service.impl;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.share.common.core.exception.ServiceException;
import com.share.common.security.utils.SecurityUtils;
import com.share.device.domain.Cabinet;
import com.share.device.domain.CabinetSlot;
import com.share.device.domain.CabinetType;
import com.share.device.domain.PowerBank;
import com.share.device.mapper.CabinetMapper;
import com.share.device.mapper.CabinetSlotMapper;
import com.share.device.mapper.CabinetTypeMapper;
import com.share.device.service.ICabinetService;
import com.share.device.service.IPowerBankService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 充电宝柜机表 服务实现类
 * </p>
 *
 * @author pww
 * @since 2025-03-24
 */
@Service
public class CabinetServiceImpl extends ServiceImpl<CabinetMapper, Cabinet> implements ICabinetService {

    @Autowired
    private CabinetMapper cabinetMapper;
    @Autowired
    private CabinetTypeMapper cabinetTypeMapper;
    @Autowired
    private CabinetSlotMapper cabinetSlotMapper;
    @Autowired
    private IPowerBankService powerBankService;

    @Override
    public List<Cabinet> selectListCabinet(Cabinet cabinet) {
        List<Cabinet> list = cabinetMapper.selectCabinetList(cabinet);
        return list;
    }

    /**
     * 新增柜机
     *
     * @param cabinet
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveCabinet(Cabinet cabinet) {
        //判断充电宝适否存在
        long count = this.count(new LambdaQueryWrapper<Cabinet>().eq(Cabinet::getCabinetNo, cabinet.getCabinetNo()));
        if (count > 0) {
            throw new RuntimeException("该充电宝柜机已存在");
        }
        //根据柜机类型id查询柜机类型
        CabinetType cabinetType = cabinetTypeMapper.selectById(cabinet.getCabinetTypeId());
        //如果柜机类型不存在 抛出异常
        if (cabinetType == null) {
            throw new RuntimeException("该柜机类型不存在");
        }
        //设置总插槽数量和可用插槽数量
        cabinet.setTotalSlots(cabinetType.getTotalSlots());
        cabinet.setFreeSlots(cabinetType.getTotalSlots());
        cabinet.setUsedSlots(0);
        cabinet.setAvailableNum(0);
        cabinet.setCreateTime(LocalDateTime.now());
        cabinet.setCreateBy(SecurityUtils.getUsername());
        this.save(cabinet);

        //获取柜机类型总插槽数量
        Integer size = cabinetType.getTotalSlots();
        for (Integer i = 0; i < size; i++) {
            CabinetSlot cabinetSlot = new CabinetSlot();
            cabinetSlot.setCabinetId(cabinet.getId());
            cabinetSlot.setSlotNo(i + 1 + "");
            cabinetSlot.setCreateTime(LocalDateTime.now());
            cabinet.setCreateBy(SecurityUtils.getUsername());
            cabinetSlotMapper.insert(cabinetSlot);
        }

        return true;
    }

    /**
     * 更新柜机
     *
     * @param cabinet
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateCabinet(Cabinet cabinet) {
        //获取旧的柜机信息
        Cabinet cabinetInfo = this.getById(cabinet.getId());
        //判断柜机是否存在
        if (cabinetInfo == null && cabinetInfo.getStatus().equals("0")) {
            throw new ServiceException("该柜机不存在或已投入使用");
        }
        //判断柜机编号是否改变
        if (!cabinetInfo.getCabinetNo().equals(cabinet.getCabinetNo())) {
            //通过柜机编号查询柜机是否存在
            long count = this.count(new LambdaQueryWrapper<Cabinet>().eq(Cabinet::getCabinetNo, cabinet.getCabinetNo()));
            //如果柜机编号存在 则抛出异常
            if (count > 0) {
                throw new ServiceException("该柜机编号已存在");
            }
        }
        //判断是否修改了柜机类型
        if (!cabinetInfo.getCabinetTypeId().equals(cabinet.getCabinetTypeId())) {
            //到这里说明修改了柜机类型 需要重置柜机插槽
            //根据柜机类型id获取柜机类型
            CabinetType cabinetType = cabinetTypeMapper.selectById(cabinet.getCabinetTypeId());
            // 设置总插槽数量和可用插槽数量
            cabinet.setTotalSlots(cabinetType.getTotalSlots());
            cabinet.setTotalSlots(cabinetType.getTotalSlots());
            cabinet.setFreeSlots(cabinetType.getTotalSlots());
            cabinet.setUsedSlots(0);
            cabinet.setAvailableNum(0);
            cabinet.setUpdateTime(LocalDateTime.now());
            cabinet.setUpdateBy(SecurityUtils.getUsername());
            this.updateById(cabinet);
            //删除所有插槽
            cabinetSlotMapper.delete(new LambdaQueryWrapper<CabinetSlot>().eq(CabinetSlot::getCabinetId, cabinet.getId()));
            Integer size = cabinetType.getTotalSlots();
            for (Integer i = 0; i < size; i++) {
                CabinetSlot cabinetSlot = new CabinetSlot();
                cabinetSlot.setCabinetId(cabinet.getId());
                cabinetSlot.setSlotNo(i + 1 + "");
                cabinetSlot.setCreateTime(LocalDateTime.now());
                cabinet.setCreateBy(SecurityUtils.getUsername());
                cabinetSlotMapper.insert(cabinetSlot);
            }
        } else {
            cabinet.setUpdateTime(LocalDateTime.now());
            cabinet.setUpdateBy(SecurityUtils.getUsername());
            this.updateById(cabinet);
        }

        return 1;
    }

    /**
     * 删除柜机
     *
     * @param ids
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int removeCabinet(List<Long> ids) {
        this.removeBatchByIds(ids);
        cabinetSlotMapper.delete(new LambdaQueryWrapper<CabinetSlot>().in(CabinetSlot::getCabinetId, ids));
        return 1;
    }

    /**
     * 查询未使用充电宝列表
     *
     * @param keyWord
     * @return
     */
    @Override
    public List<Cabinet> searchNoUseList(String keyWord) {
        return cabinetMapper.selectList(new LambdaQueryWrapper<Cabinet>().like(Cabinet::getCabinetNo, keyWord).eq(Cabinet::getStatus, "0"));
    }

    @Override
    public Map<String, Object> getAllInfo(Long id) {
        //查询柜机信息
        Cabinet cabinet = this.getById(id);

        //查询插槽信息
        List<CabinetSlot> cabinetSlotList = cabinetSlotMapper.selectList(new LambdaQueryWrapper<CabinetSlot>().eq(CabinetSlot::getCabinetId, cabinet.getId()));
        // 获取可用充电宝id列表
        List<Long> powerBankIdList = cabinetSlotList.stream().filter(item -> null != item.getPowerBankId()).map(CabinetSlot::getPowerBankId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(powerBankIdList)) {
            List<PowerBank> powerBankList = powerBankService.listByIds(powerBankIdList);
            Map<Long, PowerBank> powerBankIdToPowerBankMap = powerBankList.stream().collect(Collectors.toMap(PowerBank::getId, PowerBank -> PowerBank));
            cabinetSlotList.forEach(item -> item.setPowerBank(powerBankIdToPowerBankMap.get(item.getPowerBankId())));
        }

        Map<String, Object> result = Map.of("cabinet", cabinet, "cabinetSlotList", cabinetSlotList);
        return result;
    }


}
